package com.xqboss.apps.service.equipment;


import cn.hutool.core.bean.BeanUtil;
import com.xqboss.apps.domain.equipment.*;
import com.xqboss.apps.dto.equipment.EquipmentSmeltUserNftQueryDto;
import com.xqboss.apps.enums.market.MarketTypeEnum;
import com.xqboss.apps.service.punch.UserPunchService;
import com.xqboss.apps.vo.equipment.AppEquipmentSmeltEquipmentVo;
import com.xqboss.apps.vo.equipment.AppEquipmentSmeltEquipmentProduceVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.mapper.equipment.EquipmentSmeltTemplateNftMapper;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * 装备-熔炼模版关联藏品(EquipmentSmeltTemplateNft)表服务实现类
 *
 * @author makejava
 * @since 2024-03-01 11:51:34
 */
@Service
public class EquipmentSmeltTemplateNftService extends ServiceImpl<EquipmentSmeltTemplateNftMapper, EquipmentSmeltTemplateNft> {

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private EquipmentSmeltTemplateProduceBasicService smeltTemplateProduceBasicService;

    @Autowired
    private EquipmentSmeltTemplateProduceWorstService smeltTemplateProduceWorstService;

    @Autowired
    private UserPunchService userPunchService;


    /**
     * 装备列表
     * @param params
     * @return
     */
    public List<AppEquipmentSmeltEquipmentVo> equipmentList(EquipmentSmeltUserNftQueryDto params) {
        List<AppEquipmentSmeltEquipmentVo> list = this.baseMapper.equipmentList(params);
        if (list.isEmpty()) {
            return new ArrayList<>();
        }
        Set<Long> templateIdSet = list.stream().map(AppEquipmentSmeltEquipmentVo::getTemplateId).collect(Collectors.toSet());
        Map<Long,List<EquipmentSmeltTemplateProduceWorst>> worstListMap = smeltTemplateProduceWorstService.lambdaQuery()
                .in(EquipmentSmeltTemplateProduceWorst::getTemplateId, templateIdSet)
                .list()
                .stream()
                .collect(Collectors.groupingBy(EquipmentSmeltTemplateProduceWorst::getTemplateId));
        Map<Long,List<EquipmentSmeltTemplateProduceBasic>> basicListMap = smeltTemplateProduceBasicService.lambdaQuery()
                .in(EquipmentSmeltTemplateProduceBasic::getTemplateId, templateIdSet)
                .list()
                .stream()
                .collect(Collectors.groupingBy(EquipmentSmeltTemplateProduceBasic::getTemplateId));
        List<Equipment> equipmentList = equipmentService.lambdaQuery()
                .in(Equipment::getNftNumberId, list.stream()
                        .map(AppEquipmentSmeltEquipmentVo::getNftNumberId)
                        .collect(Collectors.toList())
                )
                .list();
        // 批量计算剩余空投
        userPunchService.calcPunchIncomeByWeakenBatch(equipmentList, false);
        Map<Long, Equipment> equipmentMap = equipmentList.stream().collect(Collectors.toMap(Equipment::getNftNumberId, v -> v));
        for (AppEquipmentSmeltEquipmentVo t : list) {
            Equipment equipment = equipmentMap.get(t.getNftNumberId());
            t.setRarity(equipment.getRarity());
            t.setLevel(equipment.getLevel());
            t.setRemainingAirdrop(equipment.getRemainingAirdrop().doubleValue());
        }
        // 通过剩余空投数判断实际产出
        for (AppEquipmentSmeltEquipmentVo t : list) {
            List<AppEquipmentSmeltEquipmentProduceVo> produceList = new ArrayList<>();
            List<EquipmentSmeltTemplateProduceBasic> basicList = basicListMap.get(t.getTemplateId());
            List<EquipmentSmeltTemplateProduceWorst> worstList = worstListMap.get(t.getTemplateId());
            // 如果系数想乘没有达到1则使用保底产出
            if (t.getRemainingAirdrop() != null && t.getRemainingAirdrop() > 0) {
                for(EquipmentSmeltTemplateProduceBasic y : basicList){
                    BigDecimal num = BigDecimal.valueOf(y.getSourceRatio() * t.getRemainingAirdrop()).setScale(2, RoundingMode.DOWN);
                    if(y.getSourceRatio() * t.getRemainingAirdrop() >= 1){
                        AppEquipmentSmeltEquipmentProduceVo produceVo = BeanUtil.copyProperties(y, AppEquipmentSmeltEquipmentProduceVo.class);
                        produceVo.setSourceNum(y.getType() == MarketTypeEnum.MATERIAL ? num.doubleValue() : num.intValue());
                        produceVo.setMethod(1);
                        produceList.add(produceVo);
                    }
                }
            }
            if (produceList.isEmpty() && worstList != null) {
                for (EquipmentSmeltTemplateProduceWorst y : worstList) {
                    AppEquipmentSmeltEquipmentProduceVo produceVo = BeanUtil.copyProperties(y, AppEquipmentSmeltEquipmentProduceVo.class);
                    produceVo.setMethod(2);
                    produceList.add(produceVo);
                }
            }
            t.setProduceList(produceList);
        }
        // 排序按照剩余空投数来排序
        list.sort((o1, o2) -> {
            if (o1.getRemainingAirdrop() == null) {
                return 1;
            }
            if (o2.getRemainingAirdrop() == null) {
                return -1;
            }
            return o1.getRemainingAirdrop().compareTo(o2.getRemainingAirdrop());
        });
        return list;
    }
}
